using System;
using System.Collections.Generic;
using System.Text;
using ET = ErlyThreads;

namespace Testbed
{
    static class TenSequencedWorkers
    {
        static ET.ProcessRuntime gThreadMaster = null;
        static string gThreadMasterID = Program.NewID();




        public static int ChainedThreadsTest()
        {
            gThreadMaster = new ET.ProcessRuntime(
                gThreadMasterID);
            string starterThreadID = Program.NewID();

            gThreadMaster.InitProcess(
                starterThreadID,
                ChainedAppWorkerThreadStart);
            gThreadMaster.StartProcess(
                starterThreadID);

            gThreadMaster.ProcessHandle.SendMessage(
                starterThreadID,
                new StartParamMessage(1));

            int returnCode = Program.SUCCESS;

            gThreadMaster.ProcessHandle.WaitForMessages();
            gThreadMaster.ProcessHandle.DispatchQueuedMessages(
                delegate(ET.ReceivedMessage newMessage)
                {
                    if (newMessage.Message.GetType() == typeof(StartParamMessage))
                    {
                        Console.WriteLine("Finished correctly");
                    }
                    else
                    {
                        Console.WriteLine("Finishe INCORRECTLY");
                        returnCode = Program.FAILURE;
                    }
                });

            return returnCode;
        }

        [Serializable]
        class StartParamMessage
        {
            public StartParamMessage(int pParamValue)
            {
                paramValue = pParamValue;
            }
            public int paramValue;
        }

        static void ChainedAppWorkerThreadStart(ET.IProcessHandle pThreadContainer)
        {
            // wait for the message to tell us
            // what our sequence number is going to be
            pThreadContainer.WaitForMessages();

            int param = -1;

            // now accept only start parameter message
            pThreadContainer.DispatchQueuedMessages(delegate(ET.ReceivedMessage message)
            {
                if (message.Message.GetType() != typeof(StartParamMessage))
                {
                    throw new ApplicationException(
                        "Received the wrong message at the wrong time");
                }

                // right, we have a parameter, lets use it
                StartParamMessage msg = message.Message as StartParamMessage;
                param = msg.paramValue;
            });

            // do the job with the paramater
            for (int i = 0 ; i < param ; i++)
            {
                Console.WriteLine(
                    "Job #{0}: Doing sub-job #{1}",
                    param,
                    i);
                System.Threading.Thread.Sleep(( new Random() ).Next(param));
            }
            Console.WriteLine();

            if (param > 10)
            {
                pThreadContainer.SendMessage(
                    gThreadMasterID,
                    new StartParamMessage(param + 1));
                return;
            }

            string newID = Program.NewID();

            gThreadMaster.InitProcess(
                newID,
                ChainedAppWorkerThreadStart);
            gThreadMaster.StartProcess(newID);

            pThreadContainer.SendMessage(
                newID,
                new StartParamMessage(param + 1));
        }
    }
}
